package com.tencent.supersonic.chat.server.rest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.tencent.supersonic.auth.api.authentication.utils.UserHolder;
import com.tencent.supersonic.chat.api.pojo.request.ChatExecuteReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatParseReq;
import com.tencent.supersonic.chat.api.pojo.request.ChatQueryDataReq;
import com.tencent.supersonic.chat.api.pojo.response.ChatParseResp;
import com.tencent.supersonic.chat.server.service.ChatQueryService;
import com.tencent.supersonic.common.pojo.User;
import com.tencent.supersonic.common.pojo.exception.InvalidArgumentException;
import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo;
import com.tencent.supersonic.headless.api.pojo.request.DimensionValueReq;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * ChatQueryController 用于处理与聊天查询相关的 API 请求。
 * 该类包含多个 POST 请求接口，用于查询、解析、执行、查询维度值等操作。
 */
@RestController
@RequestMapping({"/api/chat/query", "/openapi/chat/query"})  // 映射两个不同的路径，用于访问相同的查询接口
public class ChatQueryController {

    @Autowired
    private ChatQueryService chatQueryService;  // 注入 ChatQueryService 服务，用于处理具体的业务逻辑

    /**
     * 处理查询请求，执行搜索操作。
     * @param chatParseReq 包含查询参数的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 查询结果
     */
    @PostMapping("search")
    public Object search(@RequestBody ChatParseReq chatParseReq, HttpServletRequest request,
                         HttpServletResponse response) {
        // 设置当前请求用户
        chatParseReq.setUser(UserHolder.findUser(request, response));
        // 调用 service 层的搜索方法并返回结果
        return chatQueryService.search(chatParseReq);
    }

    /**
     * 处理解析请求，解析用户的查询内容。
     * @param chatParseReq 包含解析参数的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 解析结果
     * @throws Exception 可能抛出的异常
     */
    @PostMapping("parse")
    public Object parse(@RequestBody ChatParseReq chatParseReq, HttpServletRequest request,
                        HttpServletResponse response) throws Exception {
        // 设置当前请求用户
        chatParseReq.setUser(UserHolder.findUser(request, response));
        // 调用 service 层的解析方法并返回结果
        return chatQueryService.parse(chatParseReq);
    }

    /**
     * 处理执行请求，根据解析的结果执行查询。
     * @param chatExecuteReq 执行查询的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 执行结果
     * @throws Exception 可能抛出的异常
     */
    @PostMapping("execute")
    public Object execute(@RequestBody ChatExecuteReq chatExecuteReq, HttpServletRequest request,
                          HttpServletResponse response) throws Exception {
        // 设置当前请求用户
        chatExecuteReq.setUser(UserHolder.findUser(request, response));
        // 调用 service 层的执行方法并返回结果
        return chatQueryService.execute(chatExecuteReq);
    }

    /**
     * 处理查询请求，首先解析查询内容，然后执行查询。
     * @param chatParseReq 包含查询参数的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 查询执行结果
     * @throws Exception 可能抛出的异常
     */
    @PostMapping("/")
    public Object query(@RequestBody ChatParseReq chatParseReq, HttpServletRequest request,
                        HttpServletResponse response) throws Exception {
        // 获取当前用户信息
        User user = UserHolder.findUser(request, response);
        chatParseReq.setUser(user);  // 设置用户信息到请求对象中

        // 调用解析方法并获取解析响应
        ChatParseResp parseResp = chatQueryService.parse(chatParseReq);

        // 检查解析结果中是否有有效的解析项
        if (CollectionUtils.isEmpty(parseResp.getSelectedParses())) {
            throw new InvalidArgumentException("parser error, no selectedParses");  // 如果没有有效的解析项，抛出异常
        }

        // 获取第一个解析项（假设只有一个解析结果）
        SemanticParseInfo semanticParseInfo = parseResp.getSelectedParses().get(0);

        // 创建执行请求对象，并将解析请求的内容复制过来
        ChatExecuteReq chatExecuteReq = ChatExecuteReq.builder().build();
        BeanUtils.copyProperties(chatParseReq, chatExecuteReq);

        // 设置查询 ID 和解析 ID 到执行请求对象中
        chatExecuteReq.setQueryId(parseResp.getQueryId());
        chatExecuteReq.setParseId(semanticParseInfo.getId());

        // 调用执行方法并返回执行结果
        return chatQueryService.execute(chatExecuteReq);
    }

    /**
     * 处理查询数据请求，用于查询具体的数据。
     * @param chatQueryDataReq 包含查询数据的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 查询数据结果
     * @throws Exception 可能抛出的异常
     */
    @PostMapping("queryData")
    public Object queryData(@RequestBody ChatQueryDataReq chatQueryDataReq,
                            HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 设置当前请求用户
        chatQueryDataReq.setUser(UserHolder.findUser(request, response));
        // 调用 service 层的查询数据方法并返回结果
        return chatQueryService.queryData(chatQueryDataReq, UserHolder.findUser(request, response));
    }

    /**
     * 处理查询维度值请求，根据维度值查询相关数据。
     * @param dimensionValueReq 查询维度值的请求对象
     * @param request HttpServletRequest 对象
     * @param response HttpServletResponse 对象
     * @return 查询维度值的结果
     * @throws Exception 可能抛出的异常
     */
    @PostMapping("queryDimensionValue")
    public Object queryDimensionValue(@RequestBody @Valid DimensionValueReq dimensionValueReq,
                                      HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 调用 service 层的查询维度值方法并返回结果
        return chatQueryService.queryDimensionValue(dimensionValueReq,
                UserHolder.findUser(request, response));
    }
}
